<template>
  <div class="chat-room">
    <!-- Header -->
    <div class="chat-header">
      <div class="header-content">
        <div class="logo-section">
          <div class="logo-wrapper">
            <div class="logo-icon">🏯</div>
            <div class="logo-glow"></div>
            <div class="logo-city-badge">武汉</div>
          </div>
          <div class="title-section">
            <h1>
              <span class="title-gradient">城市向导官</span>
              <span class="title-badge">AI</span>
            </h1>
            <p class="subtitle">
              <span class="subtitle-icon">✨</span>
              <span>探索江城魅力 · 发现武汉之美</span>
            </p>
          </div>
        </div>
        <div class="weather-info">
          <div class="weather-badge">
            <span class="weather-icon">{{ weatherEmoji }}</span>
            <div class="weather-content">
              <span class="weather-label">{{ weather.location }}</span>
              <span class="weather-temp">{{ weather.temperature }}°C · {{ weather.text }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Messages Container -->
    <div class="messages-container" ref="messagesContainer">
      <div class="welcome-message" v-if="messages.length === 0">
        <div class="welcome-card">
          <div class="icon-circle">
            <div class="welcome-icon">🏯</div>
            <div class="circle-ring"></div>
            <div class="circle-ring-2"></div>
          </div>

          <h2>你好！我是武汉城市向导 AI</h2>
          <p class="welcome-desc">我可以为您提供武汉的景点推荐、美食攻略、交通路线、文化历史等全方位信息</p>

          <div class="feature-grid">
            <div class="feature-item">
              <div class="feature-icon">🏯</div>
              <div class="feature-text">景点推荐</div>
            </div>
            <div class="feature-item">
              <div class="feature-icon">🍜</div>
              <div class="feature-text">美食攻略</div>
            </div>
            <div class="feature-item">
              <div class="feature-icon">🚇</div>
              <div class="feature-text">交通指引</div>
            </div>
            <div class="feature-item">
              <div class="feature-icon">🎭</div>
              <div class="feature-text">文化历史</div>
            </div>
          </div>

          <div class="divider">
            <span>💡 试试这些问题</span>
          </div>

          <div class="suggestion-grid">
            <button
                class="suggestion-btn"
                v-for="(suggestion, index) in suggestions"
                :key="suggestion"
                @click="sendSuggestion(suggestion)"
            >
              <span class="suggestion-icon">{{ suggestionIcons[index] }}</span>
              <span class="suggestion-text">{{ suggestion }}</span>
              <span class="suggestion-arrow">→</span>
            </button>
          </div>
        </div>
      </div>

      <div v-for="(msg, index) in messages" :key="index" class="message-wrapper" :class="[msg.role, msg.messageType]">
        <div class="message-bubble">
          <div class="message-content" :class="msg.role">
            <div v-if="msg.role === 'assistant' && !msg.content && isLoading" class="typing-indicator">
              <div class="typing-dot"></div>
              <div class="typing-dot"></div>
              <div class="typing-dot"></div>
            </div>
            <div v-else>
              <div class="message-text" :class="{ 'manus-mode': msg.isManusMode, [msg.messageType]: msg.messageType }" v-html="formatMessage(msg.content, msg.isManusMode, msg.messageType)"></div>
              
              <!-- 网页搜索卡片 -->
              <div v-if="msg.webSearch" class="web-search-card">
                <div class="web-search-header" @click="msg.webSearchExpanded = !msg.webSearchExpanded">
                  <div class="web-search-icon">🔍</div>
                  <div class="web-search-info">
                    <div class="web-search-title">{{ msg.webSearch.toolName }}</div>
                    <div class="web-search-meta">
                      {{ msg.webSearch.urls.length }} 个网页 • 点击展开查看
                    </div>
                  </div>
                  <div class="expand-icon" :class="{ 'expanded': msg.webSearchExpanded }">
                    ▼
                  </div>
                </div>
                <transition name="slide-fade">
                  <div v-if="msg.webSearchExpanded" class="web-search-content">
                    <div class="url-list">
                      <div 
                        v-for="(url, index) in msg.webSearch.urls" 
                        :key="index"
                        class="url-item"
                      >
                        <span class="url-number">{{ index + 1 }}</span>
                        <a :href="url" target="_blank" class="url-link" @click.stop>
                          {{ url }}
                        </a>
                      </div>
                    </div>
                  </div>
                </transition>
              </div>
              
              <!-- PDF文件卡片 -->
              <div v-if="msg.pdfFile" class="pdf-card">
                <div class="pdf-card-header">
                  <div class="pdf-icon">📄</div>
                  <div class="pdf-info">
                    <div class="pdf-title">{{ msg.pdfFile.fileName }}</div>
                    <div class="pdf-meta">PDF文档 • 点击查看或下载</div>
                  </div>
                </div>
                <div class="pdf-card-actions">
                  <button class="pdf-btn pdf-btn-preview" @click="previewPDF(msg.pdfFile.fileName)">
                    <span class="btn-icon">👁️</span>
                    <span>查看</span>
                  </button>
                  <button class="pdf-btn pdf-btn-download" @click="downloadPDF(msg.pdfFile.fileName)">
                    <span class="btn-icon">⬇️</span>
                    <span>下载</span>
                  </button>
                </div>
              </div>
              
              <div class="message-time">
                <span class="time-icon">{{ getTimeIcon(msg.messageType, msg.isManusMode) }}</span>
                <span>{{ msg.time }}</span>
                <span v-if="msg.isManusMode" class="mode-badge" :class="msg.messageType">
                  {{ getModeBadge(msg.messageType) }}
                </span>
              </div>
            </div>
          </div>
          <div class="message-avatar" :class="msg.role">
            <span class="avatar-emoji">{{ getAvatarEmoji(msg.role, msg.isManusMode, msg.messageType) }}</span>
            <div class="avatar-ring" :class="msg.messageType"></div>
          </div>
        </div>
      </div>
    </div>

    <!-- Input Area -->
    <div class="input-area">
      <div class="input-container" :class="{ 'focused': isFocused || inputMessage }">
        <div class="input-wrapper">
          <label class="floating-label" :class="{ 'active': isFocused || inputMessage }">
            <span class="label-icon">✍️</span>
            <span>请输入您想了解的武汉信息...</span>
          </label>
          <div class="input-box">
            <textarea
                v-model="inputMessage"
                @focus="isFocused = true"
                @blur="isFocused = false"
                @keydown.enter.exact.prevent="sendMessage"
                @keydown.enter.shift.exact="inputMessage += '\n'"
                placeholder=""
                rows="1"
                ref="textareaRef"
                :disabled="isLoading"
            ></textarea>
            <div class="action-buttons">
              <button
                  class="send-button"
                  @click="sendMessage"
                  :disabled="!inputMessage.trim() || isLoading"
                  :class="{ 'active': inputMessage.trim() }"
              >
                <svg v-if="!isLoading" class="send-icon" width="20" height="20" viewBox="0 0 24 24" fill="none">
                  <path d="M22 2L11 13M22 2L15 22L11 13L2 9L22 2Z" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                <div v-else class="loading-spinner">
                  <div class="spinner-ring"></div>
                </div>
              </button>
            </div>
          </div>
          <div class="input-hint">
            <button 
              class="manus-tag" 
              :class="{ 'active': isManusMode }"
              @click="toggleManusMode"
              type="button"
              title="制作旅游攻略PDF"
            >
              <span class="tag-icon">🤖</span>
              <span class="tag-text">Manus 模式</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted, watch, computed } from 'vue'
import { chatWithSSE, chatWithManusSSE } from '../api/chat'
import { generateUUID } from '../utils/uuid'
import { getWeather, getWeatherEmoji } from '../api/weather'

const chatId = ref('')
const inputMessage = ref('')
const messages = ref([])
const isLoading = ref(false)
const messagesContainer = ref(null)
const textareaRef = ref(null)
const isFocused = ref(false)
const isManusMode = ref(false)

// 天气相关
const weather = ref({
  location: '武汉',
  temperature: '--',
  text: '加载中...',
  code: '99'
})

const weatherEmoji = computed(() => getWeatherEmoji(weather.value.code))

const suggestions = [
  '推荐武汉必去景点',
  '武汉特色美食推荐',
  '黄鹤楼游玩攻略',
  '武汉三日游路线规划'
]

const suggestionIcons = ['🏛️', '🍜', '🏯', '🗺️']

onMounted(async () => {
  chatId.value = generateUUID()
  
  // 获取武汉天气
  const weatherData = await getWeather('wuhan')
  weather.value = weatherData
  
  // 每30分钟更新一次天气
  setInterval(async () => {
    const weatherData = await getWeather('wuhan')
    weather.value = weatherData
  }, 30 * 60 * 1000)
})

// Auto-resize textarea
watch(inputMessage, () => {
  nextTick(() => {
    if (textareaRef.value) {
      textareaRef.value.style.height = 'auto'
      textareaRef.value.style.height = textareaRef.value.scrollHeight + 'px'
    }
  })
})

const sendSuggestion = (suggestion) => {
  inputMessage.value = suggestion
  sendMessage()
}

const sendMessage = async () => {
  if (!inputMessage.value.trim() || isLoading.value) return

  const userMessage = inputMessage.value.trim()
  inputMessage.value = ''

  // Reset textarea height
  if (textareaRef.value) {
    textareaRef.value.style.height = 'auto'
  }

  // Add user message
  messages.value.push({
    role: 'user',
    content: userMessage,
    time: getCurrentTime()
  })

  scrollToBottom(true) // 强制滚动到底部
  isLoading.value = true

  try {
    // 根据 Manus 模式选择不同的 API
    if (isManusMode.value) {
      // Manus 模式：分步骤显示（参考 SuperAgent.vue）
      isLoading.value = true
      
      // 添加思考状态消息
      messages.value.push({
        role: 'assistant',
        content: '🔍 正在分析您的需求...',
        time: getCurrentTime(),
        isManusMode: true,
        messageType: 'ai-thinking'
      })
      scrollToBottom(true)
      
      // 用于管理响应的变量
      let messageBuffer = []
      let currentStepNumber = 1
      let lastBubbleTime = Date.now()
      let isCompleted = false
      let isFirstResponse = true
      
      const chineseEndPunctuation = ['。', '！', '？', '…', '\n\n']
      const minBubbleInterval = 800 // 最小间隔800ms
      
      // 提取网页 URL 的函数
      const extractUrls = (content) => {
        const urlRegex = /https?:\/\/[^\s]+/gi
        const urls = content.match(urlRegex) || []
        
        // 清理每个URL，去掉末尾的换行符、反斜杠n等
        return urls.map(url => {
          // 去掉末尾的 \n, \\n, 以及其他空白字符
          return url.replace(/\\n$/, '')
                   .replace(/\n$/, '')
                   .replace(/\r$/, '')
                   .trim()
        })
      }
      
      // 提取文件路径的函数
      const extractFilePaths = (content) => {
        const filePathRegex = /(?:生成|保存|下载|创建).*?(?:PDF|文件|图片).*?(?:到|至|路径)?[：:]?\s*([C-Z]:[\\\/][\w\s\-\\\/\.]+\.(?:pdf|txt|jpg|jpeg|png|doc|docx|xls|xlsx))/gi
        const matches = []
        let match
        while ((match = filePathRegex.exec(content)) !== null) {
          matches.push(match[1].trim())
        }
        return matches
      }
      
      // 提取PDF文件名的函数
      const extractPDFFileName = (content) => {
        console.log('尝试提取PDF文件名，内容:', content.substring(0, 200))
        
        // 策略1: 匹配 "📄 文件名: xxx.pdf" 或 "文件名: xxx.pdf" 格式
        const fileNameMatch = content.match(/(?:📄\s*)?文件名[:：]\s*(.+?\.pdf)(?:\s*\n|$)/i)
        if (fileNameMatch) {
          const fileName = fileNameMatch[1].trim()
          console.log('✅ 策略1匹配成功:', fileName)
          return fileName
        }
        
        // 策略2: 匹配 "PDF文件生成成功" 后的内容
        const successMatch = content.match(/PDF.*?生成.*?成功.*?[:：]?\s*([a-zA-Z0-9_\-\u4e00-\u9fa5]+\.pdf)/i)
        if (successMatch) {
          const fileName = successMatch[1].trim()
          console.log('✅ 策略2匹配成功:', fileName)
          return fileName
        }
        
        // 策略3: 从完整路径中提取文件名（匹配最后一个斜杠后的内容）
        const pathMatch = content.match(/[/\\]([^/\\]+?\.pdf)(?:\s*\n|$)/i)
        if (pathMatch) {
          const fileName = pathMatch[1].trim()
          console.log('✅ 策略3匹配成功:', fileName)
          return fileName
        }
        
        // 策略4: 匹配任何看起来像文件名的 .pdf
        const simpleMatch = content.match(/\b([a-zA-Z0-9_\-\u4e00-\u9fa5]+\.pdf)\b/i)
        if (simpleMatch) {
          const fileName = simpleMatch[1].trim()
          console.log('✅ 策略4匹配成功:', fileName)
          return fileName
        }
        
        console.warn('❌ 所有策略都未能提取PDF文件名')
        return null
      }
      
      // 判断是否为网页搜索/抓取结果
      const isWebSearchResult = (content) => {
        const lower = content.toLowerCase()
        return (lower.includes('搜索结果') || lower.includes('search result') || 
                lower.includes('网页内容') || lower.includes('web content') ||
                lower.includes('抓取') || lower.includes('scrape')) &&
               extractUrls(content).length > 0
      }
      
      // 简化网页搜索/抓取结果并提取URL信息
      const simplifyWebContent = (content) => {
        const urls = extractUrls(content)
        if (urls.length === 0) return { content, urls: [] }
        
        // 提取工具名称
        let toolName = ''
        if (content.includes('SearchEngine') || content.includes('搜索')) {
          toolName = '🔍 网页搜索'
        } else if (content.includes('WebScraper') || content.includes('抓取')) {
          toolName = '🌐 网页抓取'
        }
        
        // 构建简化版本
        let simplified = toolName ? `${toolName}` : '🌐 网页内容获取'
        simplified += `\n\n已成功获取 ${urls.length} 个网页的内容`
        
        return { content: simplified, urls }
      }
      
      // 创建新的响应气泡
      const createResponseBubble = (content, type = 'ai-step') => {
        if (!content.trim()) return
        
        const now = Date.now()
        const timeSinceLastBubble = now - lastBubbleTime
        
        // 移除思考状态（仅在第一次响应时）
        if (isFirstResponse) {
          messages.value = messages.value.filter(msg => msg.type !== 'ai-thinking' || msg.content !== '🔍 正在分析您的需求...')
          isFirstResponse = false
        }
        
        // 检测是否为网页搜索/抓取结果
        let finalContent = content
        let webSearchInfo = null
        
        if (isWebSearchResult(content)) {
          const result = simplifyWebContent(content)
          finalContent = result.content
          if (result.urls && result.urls.length > 0) {
            webSearchInfo = {
              urls: result.urls,
              toolName: finalContent.split('\n')[0] // 第一行作为工具名称
            }
          }
        }
        
        // 检查是否包含PDF文件生成信息
        const pdfFileName = extractPDFFileName(content)
        let pdfFileInfo = null
        
        console.log('PDF文件名提取结果:', pdfFileName)
        
        // 检查是否包含文件生成信息
        const filePaths = extractFilePaths(content)
        console.log('文件路径提取结果:', filePaths)
        
        if (filePaths.length > 0 || pdfFileName) {
          // 如果是 PDF 工具，只输出文件路径
          finalContent = `📁 PDF 文件已生成\n\n`
          type = 'ai-file-summary'
          
          // 如果提取到PDF文件名，保存到消息对象中
          if (pdfFileName) {
            pdfFileInfo = {
              fileName: pdfFileName
            }
            console.log('✅ 将添加PDF文件信息到消息:', pdfFileInfo)
          } else {
            console.warn('⚠️ 未能提取PDF文件名，卡片将不会显示')
          }
        }
        
        // 格式化步骤内容
        let formattedContent = finalContent
        if (type === 'ai-step' && !finalContent.includes('Step') && !finalContent.includes('步骤')) {
          formattedContent = `**步骤 ${currentStepNumber}**: ${finalContent}`
          currentStepNumber++
        }
        
        const addBubble = () => {
          messages.value.push({
            role: 'assistant',
            content: formattedContent,
            time: getCurrentTime(),
            isManusMode: true,
            messageType: type,
            pdfFile: pdfFileInfo,  // 添加PDF文件信息
            webSearch: webSearchInfo  // 添加网页搜索信息
          })
          scrollToBottom()
        }
        
        if (timeSinceLastBubble < minBubbleInterval) {
          setTimeout(addBubble, minBubbleInterval - timeSinceLastBubble)
        } else {
          addBubble()
        }
        
        lastBubbleTime = now
        messageBuffer = []
      }
      
      await chatWithManusSSE(
          userMessage,
          (chunk) => {
            messageBuffer.push(chunk)
            const combinedText = messageBuffer.join('')
            
            // 检查是否应该创建新气泡
            const lastChar = chunk.charAt(chunk.length - 1)
            const hasCompleteSentence = chineseEndPunctuation.some(punct =>
                lastChar === punct || chunk.includes(punct)
            )
            const isLongEnough = combinedText.length > 60
            
            // 检测步骤标识符
            const stepIndicators = ['Step', 'step', '步骤', '第', '正在', '开始', '完成', '任务结束']
            const hasStepIndicator = stepIndicators.some(indicator =>
                combinedText.toLowerCase().includes(indicator.toLowerCase())
            )
            
            if (hasCompleteSentence || isLongEnough || hasStepIndicator) {
              // 判断消息类型
              let messageType = 'ai-step'
              if (combinedText.includes('任务结束') || combinedText.includes('Terminated')) {
                messageType = 'ai-completion'
                isCompleted = true
              } else if (combinedText.includes('错误') || combinedText.includes('失败') || combinedText.includes('Error')) {
                messageType = 'ai-error'
              } else if (combinedText.includes('完成') || combinedText.includes('结束') || combinedText.includes('successfully')) {
                messageType = 'ai-final'
              } else if (combinedText.includes('搜索') || combinedText.includes('查找') || combinedText.includes('search')) {
                messageType = 'ai-search'
              } else if (combinedText.includes('分析') || combinedText.includes('处理') || combinedText.includes('analysis')) {
                messageType = 'ai-analysis'
              } else if (combinedText.includes('生成') || combinedText.includes('创建') || combinedText.includes('generate')) {
                messageType = 'ai-generation'
              }
              
              createResponseBubble(combinedText, messageType)
            }
          },
          () => {
            // On complete
            isCompleted = true
            
            // 处理剩余内容
            if (messageBuffer.length > 0) {
              const remainingContent = messageBuffer.join('')
              createResponseBubble(remainingContent, 'ai-final')
            }
            
            // 添加完成消息
            setTimeout(() => {
              messages.value.push({
                role: 'assistant',
                content: '✅ 任务执行完成！如需进一步帮助，请继续提问',
                time: getCurrentTime(),
                isManusMode: true,
                messageType: 'ai-completion'
              })
              scrollToBottom()
              isLoading.value = false
            }, 500)
          },
          (error) => {
            // On error
            if (isCompleted) {
              console.log('Task completed normally, ignoring connection error')
              isLoading.value = false
              return
            }
            
            isLoading.value = false
            messages.value = messages.value.filter(msg => msg.content !== '🔍 正在分析您的需求...')
            messages.value.push({
              role: 'assistant',
              content: '⚠️ Manus 连接中断，请检查网络后重试',
              time: getCurrentTime(),
              isManusMode: true,
              messageType: 'ai-error'
            })
            console.error('Manus SSE Error:', error)
          }
      )
    } else {
      // 普通模式：单一流式响应
      const assistantMessageIndex = messages.value.length
      messages.value.push({
        role: 'assistant',
        content: '',
        time: getCurrentTime(),
        isManusMode: false,
        messageType: ''
      })
      
      await chatWithSSE(
          userMessage,
          chatId.value,
          (chunk) => {
            // Update assistant message with streaming content
            messages.value[assistantMessageIndex].content += chunk
            scrollToBottom() // 只在用户在底部时自动滚动
          },
          () => {
            // On complete
            isLoading.value = false
            messages.value[assistantMessageIndex].time = getCurrentTime()
          },
          (error) => {
            // On error
            isLoading.value = false
            messages.value[assistantMessageIndex].content = '❌ 连接失败：请确保后端服务已启动在 http://localhost:8123\n\n如果服务已启动，可能是 CORS 跨域问题，请检查后端 CORS 配置。'
            console.error('SSE Error:', error)
          }
      )
    }
  } catch (error) {
    isLoading.value = false
    // 在 Manus 模式下添加错误消息
    if (isManusMode.value) {
      messages.value.push({
        role: 'assistant',
        content: '❌ 连接异常：请检查网络连接和后端服务状态。',
        time: getCurrentTime(),
        isManusMode: true,
        messageType: 'ai-error'
      })
    }
    console.error('Chat Error:', error)
  }
}

const toggleManusMode = () => {
  isManusMode.value = !isManusMode.value
}

// 检测消息类型（参考 SuperAgent.vue）
const detectMessageType = (content) => {
  if (!content) return 'ai-thinking'
  
  const lowerContent = content.toLowerCase()
  
  // 检测各种消息类型
  if (lowerContent.includes('step') || lowerContent.includes('步骤') || /第\s*\d+\s*步/.test(content)) {
    return 'ai-step'
  }
  if (lowerContent.includes('任务结束') || lowerContent.includes('terminated') || lowerContent.includes('任务完成')) {
    return 'ai-completion'
  }
  if (lowerContent.includes('错误') || lowerContent.includes('失败') || lowerContent.includes('error')) {
    return 'ai-error'
  }
  if (lowerContent.includes('搜索') || lowerContent.includes('查找') || lowerContent.includes('search')) {
    return 'ai-search'
  }
  if (lowerContent.includes('分析') || lowerContent.includes('处理') || lowerContent.includes('analysis')) {
    return 'ai-analysis'
  }
  if (lowerContent.includes('生成') || lowerContent.includes('创建') || lowerContent.includes('generate')) {
    return 'ai-generation'
  }
  if (lowerContent.includes('完成') || lowerContent.includes('结束') || lowerContent.includes('successfully')) {
    return 'ai-final'
  }
  if (lowerContent.includes('pdf') || lowerContent.includes('文件') || lowerContent.includes('下载')) {
    return 'ai-file-summary'
  }
  
  return 'ai-step'
}

// 获取时间图标
const getTimeIcon = (messageType, isManusMode) => {
  if (!isManusMode) return '🕐'
  
  const icons = {
    'ai-thinking': '🤔',
    'ai-step': '⚙️',
    'ai-search': '🔍',
    'ai-analysis': '📊',
    'ai-generation': '✨',
    'ai-final': '✅',
    'ai-completion': '🎉',
    'ai-error': '⚠️',
    'ai-file-summary': '📁'
  }
  return icons[messageType] || '🕐'
}

// 获取模式徽章文本
const getModeBadge = (messageType) => {
  const badges = {
    'ai-thinking': '🤖 思考中',
    'ai-step': '⚙️ 执行中',
    'ai-search': '🔍 搜索中',
    'ai-analysis': '📊 分析中',
    'ai-generation': '✨ 生成中',
    'ai-final': '✅ 已完成',
    'ai-completion': '🎉 全部完成',
    'ai-error': '⚠️ 错误',
    'ai-file-summary': '📁 文件就绪'
  }
  return badges[messageType] || '📄 Manus'
}

// 获取头像表情
const getAvatarEmoji = (role, isManusMode, messageType) => {
  if (role === 'user') return '👤'
  if (!isManusMode) return '🤖'
  
  const avatars = {
    'ai-thinking': '🤔',
    'ai-search': '🔍',
    'ai-analysis': '📊',
    'ai-generation': '✨',
    'ai-completion': '🎉',
    'ai-error': '⚠️',
    'ai-file-summary': '📁'
  }
  return avatars[messageType] || '⚙️'
}

const isNearBottom = () => {
  if (!messagesContainer.value) return true
  const threshold = 100 // 距离底部100px内认为是在底部
  const scrollTop = messagesContainer.value.scrollTop
  const scrollHeight = messagesContainer.value.scrollHeight
  const clientHeight = messagesContainer.value.clientHeight
  return scrollHeight - scrollTop - clientHeight < threshold
}

const scrollToBottom = async (force = false) => {
  await nextTick()
  if (messagesContainer.value) {
    // 如果强制滚动，或者用户已经在底部附近，才自动滚动
    if (force || isNearBottom()) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
    }
  }
}

const getCurrentTime = () => {
  const now = new Date()
  return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`
}

// 预览PDF文件
const previewPDF = (fileName) => {
  console.log('预览PDF文件:', fileName)
  const url = `http://localhost:8123/api/file/pdf/preview?fileName=${encodeURIComponent(fileName)}`
  console.log('预览URL:', url)
  window.open(url, '_blank')
}

// 下载PDF文件
// 使用简单的 <a> 标签方式，避免被IDM拦截，兼容性更好
const downloadPDF = (fileName) => {
  console.log('📥 开始下载PDF文件:', fileName)
  const url = `http://localhost:8123/api/file/pdf/download?fileName=${encodeURIComponent(fileName)}`
  console.log('📍 下载URL:', url)
  
  // 创建隐藏的 <a> 标签触发下载
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  link.style.display = 'none'
  link.target = '_blank'  // 在新标签页打开，避免影响当前页面
  
  // 添加到DOM并触发点击
  document.body.appendChild(link)
  console.log('🔗 触发下载...')
  link.click()
  
  // 延迟移除元素
  setTimeout(() => {
    document.body.removeChild(link)
    console.log('✅ 下载已触发')
  }, 100)
  
  // 注意：此方法无法检测下载是否成功，但兼容性最好
  // 如果文件不存在，浏览器会显示404页面
}

const formatMessage = (text, isManusMode = false, messageType = '') => {
  if (!text) return ''
  
  if (isManusMode) {
    // Manus 模式：更精致的格式化（参考 SuperAgent.vue）
    let formatted = text
    
    // 1. 处理 Step 步骤（参考 SuperAgent.vue）
    formatted = formatted.replace(
      /Step\s+(\d+):\s*工具\s+(\w+)\s*-\s*(.*?)(?=Step\s+\d+:|$)/gs,
      (match, stepNum, toolName, content) => {
        return `<div class="manus-step-block">
          <div class="manus-step-header">
            <span class="step-number">Step ${stepNum}</span>
            <span class="step-tool">🔧 ${toolName}</span>
          </div>
          <div class="manus-step-content">${content.trim()}</div>
        </div>`
      }
    )
    
    // 2. 处理中文步骤标题
    formatted = formatted.replace(
      /^(步骤|第)\s*(\d+)\s*(步|：|:)\s*(.*?)$/gm,
      '<div class="manus-step-title"><span class="step-badge">步骤 $2</span><span class="step-desc">$4</span></div>'
    )
    
    // 3. 处理标题（## 标题）
    formatted = formatted
      .replace(/^### (.*?)$/gm, '<h4 class="manus-h4">$1</h4>')
      .replace(/^## (.*?)$/gm, '<h3 class="manus-h3">$1</h3>')
      .replace(/^# (.*?)$/gm, '<h2 class="manus-h2">$1</h2>')
    
    // 4. 处理有序列表
    formatted = formatted.replace(/^\d+\.\s+(.*?)$/gm, '<div class="manus-list-item">$1</div>')
    
    // 5. 处理无序列表
    formatted = formatted.replace(/^[-*]\s+(.*?)$/gm, '<div class="manus-bullet-item">• $1</div>')
    
    // 6. 处理工具调用提示
    formatted = formatted.replace(
      /(调用工具|使用工具|Tool|tool)[:：]\s*(\w+)/g,
      '<span class="tool-badge">🔧 $2</span>'
    )
    
    // 7. 处理文件路径
    formatted = formatted.replace(
      /([C-Z]:[\\\/][\w\s\-\\\/\.]+\.(?:pdf|txt|jpg|jpeg|png|doc|docx|xls|xlsx))/gi,
      '<span class="file-path">📄 $1</span>'
    )
    
    // 8. 处理粗体和斜体
    formatted = formatted
      .replace(/\*\*(.*?)\*\*/g, '<strong class="manus-bold">$1</strong>')
      .replace(/\*(.*?)\*/g, '<em class="manus-italic">$1</em>')
    
    // 9. 处理代码块
    formatted = formatted.replace(/`([^`]+)`/g, '<code class="manus-code">$1</code>')
    
    // 10. 处理分隔符
    formatted = formatted.replace(/^---$/gm, '<hr class="manus-divider">')
    
    // 11. 处理链接 [文本](URL)
    formatted = formatted.replace(
      /\[([^\]]+)\]\(([^)]+)\)/g,
      '<a href="$2" class="manus-link" target="_blank">$1 🔗</a>'
    )
    
    // 12. 处理表情符号增强（在行首的表情）
    formatted = formatted.replace(
      /^([\u{1F300}-\u{1F9FF}])\s+(.*?)$/gmu,
      '<div class="manus-emoji-line"><span class="manus-emoji">$1</span><span>$2</span></div>'
    )
    
    // 13. 处理换行
    formatted = formatted
      .replace(/\n\n/g, '<div class="manus-paragraph-break"></div>')
      .replace(/\n/g, '<br>')
    
    return formatted
  } else {
    // 普通模式：简单格式化
    return text
      .replace(/\n/g, '<br>')
      .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
      .replace(/\*(.*?)\*/g, '<em>$1</em>')
  }
}
</script>

<style scoped>
* {
  box-sizing: border-box;
}

.chat-room {
  width: 100%;
  max-width: 1200px;
  height: 90vh;
  max-height: 900px;
  background: #ffffff;
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.04);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

/* Header */
.chat-header {
  background: linear-gradient(135deg, #0EA5E9 0%, #06B6D4 50%, #10B981 100%);
  padding: 28px 36px;
  position: relative;
  overflow: hidden;
}

.chat-header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 100%);
  pointer-events: none;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  z-index: 1;
}

.logo-section {
  display: flex;
  align-items: center;
  gap: 20px;
}

.logo-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.logo-icon {
  font-size: 56px;
  position: relative;
  z-index: 2;
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.2));
}

.logo-glow {
  position: absolute;
  width: 80px;
  height: 80px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.3) 0%, transparent 70%);
  border-radius: 50%;
  animation: pulse 2s ease-in-out infinite;
}

.logo-city-badge {
  position: absolute;
  bottom: -4px;
  right: -8px;
  background: rgba(255, 255, 255, 0.95);
  color: #0EA5E9;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 3;
  letter-spacing: 0.5px;
  border: 1px solid rgba(255, 255, 255, 0.5);
}

@keyframes float {
  0%, 100% { transform: translateY(0px); }
  50% { transform: translateY(-8px); }
}

@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 0.5; }
  50% { transform: scale(1.2); opacity: 0.8; }
}

.title-section h1 {
  font-size: 32px;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  color: white;
}

.title-gradient {
  background: linear-gradient(135deg, #ffffff 0%, #f0f0ff 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  letter-spacing: 0.5px;
}

.title-badge {
  background: rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(10px);
  color: white;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 12px;
  letter-spacing: 1px;
  border: 1px solid rgba(255, 255, 255, 0.3);
}

.subtitle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  color: rgba(255, 255, 255, 0.95);
  margin-top: 8px;
  font-weight: 400;
}

.subtitle-icon {
  font-size: 16px;
  animation: sparkle 2s ease-in-out infinite;
}

@keyframes sparkle {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(1.2); }
}

.weather-info {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.weather-badge {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(10px);
  padding: 10px 18px;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  cursor: default;
}

.weather-badge:hover {
  background: rgba(255, 255, 255, 0.25);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

.weather-icon {
  font-size: 24px;
  animation: weatherFloat 3s ease-in-out infinite;
}

@keyframes weatherFloat {
  0%, 100% { transform: translateY(0px) rotate(0deg); }
  50% { transform: translateY(-4px) rotate(5deg); }
}

.weather-content {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.weather-label {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.85);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.weather-temp {
  font-size: 13px;
  color: white;
  font-weight: 700;
  letter-spacing: 0.3px;
}

/* Messages */
.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 32px;
  background: linear-gradient(180deg, #fafafa 0%, #f5f5f5 100%);
}

.messages-container::-webkit-scrollbar {
  width: 8px;
}

.messages-container::-webkit-scrollbar-track {
  background: transparent;
}

.messages-container::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 4px;
}

.messages-container::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.15);
}

/* Welcome Message */
.welcome-message {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100%;
  padding: 40px 20px;
}

.welcome-card {
  max-width: 700px;
  width: 100%;
  animation: fadeInUp 0.6s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.icon-circle {
  position: relative;
  width: 120px;
  height: 120px;
  margin: 0 auto 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.welcome-icon {
  font-size: 64px;
  position: relative;
  z-index: 3;
  animation: bounce 2s ease-in-out infinite;
}

@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-12px); }
}

.circle-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 3px solid #0EA5E9;
  border-radius: 50%;
  opacity: 0.3;
  animation: ripple 2s ease-out infinite;
}

.circle-ring-2 {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 3px solid #06B6D4;
  border-radius: 50%;
  opacity: 0.2;
  animation: ripple 2s ease-out infinite 1s;
}

@keyframes ripple {
  0% {
    transform: scale(1);
    opacity: 0.3;
  }
  100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

.welcome-card h2 {
  font-size: 32px;
  color: #1f2937;
  margin-bottom: 16px;
  font-weight: 700;
  text-align: center;
  line-height: 1.3;
}

.welcome-desc {
  font-size: 16px;
  color: #6b7280;
  text-align: center;
  line-height: 1.6;
  margin-bottom: 40px;
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 40px;
}

.feature-item {
  background: white;
  padding: 20px;
  border-radius: 16px;
  text-align: center;
  border: 2px solid #f3f4f6;
  transition: all 0.3s ease;
  cursor: default;
}

.feature-item:hover {
  border-color: #0EA5E9;
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(14, 165, 233, 0.15);
}

.feature-icon {
  font-size: 36px;
  margin-bottom: 8px;
}

.feature-text {
  font-size: 14px;
  color: #4b5563;
  font-weight: 600;
}

.divider {
  text-align: center;
  margin: 32px 0 24px;
  position: relative;
}

.divider span {
  background: linear-gradient(180deg, #fafafa 0%, #f5f5f5 100%);
  padding: 0 16px;
  font-size: 14px;
  color: #9ca3af;
  font-weight: 600;
  position: relative;
  z-index: 1;
}

.divider::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
  background: #e5e7eb;
}

.suggestion-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.suggestion-btn {
  background: white;
  border: 2px solid #e5e7eb;
  padding: 16px 20px;
  border-radius: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  transition: all 0.3s ease;
  text-align: left;
}

.suggestion-btn:hover {
  border-color: #0EA5E9;
  background: linear-gradient(135deg, #0EA5E9 0%, #06B6D4 100%);
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(14, 165, 233, 0.3);
}

.suggestion-btn:hover .suggestion-text {
  color: white;
}

.suggestion-btn:hover .suggestion-arrow {
  color: white;
  transform: translateX(4px);
}

.suggestion-icon {
  font-size: 24px;
  flex-shrink: 0;
}

.suggestion-text {
  flex: 1;
  font-size: 15px;
  color: #374151;
  font-weight: 600;
  transition: color 0.3s ease;
}

.suggestion-arrow {
  font-size: 18px;
  color: #9ca3af;
  transition: all 0.3s ease;
}

/* Message Bubbles */
.message-wrapper {
  margin-bottom: 24px;
  animation: slideIn 0.4s ease-out;
}

/* Manus 模式连续消息间距缩小 */
.message-wrapper.assistant + .message-wrapper.assistant {
  margin-top: -12px;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-bubble {
  display: flex;
  gap: 16px;
  max-width: 75%;
  width: fit-content;
}

/* AI消息：头像在左，内容在右 */
.assistant .message-bubble {
  flex-direction: row;
}

/* 用户消息：内容在左，头像在右，整体靠右 */
.user .message-bubble {
  margin-left: auto;
}

.message-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  flex-shrink: 0;
  background: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  position: relative;
  border: 3px solid #f3f4f6;
}

/* AI头像在左边（order: 0） */
.assistant .message-avatar {
  order: 0;
}

/* 用户头像在右边（order: 2） */
.user .message-avatar {
  order: 2;
}

.avatar-emoji {
  position: relative;
  z-index: 2;
}

.avatar-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 2px solid #0EA5E9;
  border-radius: 50%;
  opacity: 0;
  animation: avatarPulse 2s ease-out infinite;
}

@keyframes avatarPulse {
  0% {
    transform: scale(1);
    opacity: 0.5;
  }
  100% {
    transform: scale(1.3);
    opacity: 0;
  }
}

.message-content {
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* AI消息内容在右边（order: 1） */
.assistant .message-content {
  align-items: flex-start;
  order: 1;
}

/* 用户消息内容在左边（order: 1） */
.user .message-content {
  align-items: flex-end;
  order: 1;
}

.message-text {
  background: white;
  padding: 16px 20px;
  border-radius: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  line-height: 1.7;
  color: #1f2937;
  font-size: 15px;
  word-wrap: break-word;
  border: 1px solid #f3f4f6;
}

.user .message-text {
  background: linear-gradient(135deg, #0EA5E9 0%, #06B6D4 100%);
  color: white;
  border: none;
  box-shadow: 0 4px 12px rgba(14, 165, 233, 0.3);
}

.message-time {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #9ca3af;
  margin-top: 8px;
  padding: 0 8px;
}

.time-icon {
  font-size: 14px;
}

.mode-badge {
  background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
  color: white;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  margin-left: 4px;
  box-shadow: 0 2px 6px rgba(139, 92, 246, 0.3);
  transition: all 0.3s ease;
}

/* 不同消息类型的徽章颜色（参考 SuperAgent.vue） */
.mode-badge.ai-thinking {
  background: linear-gradient(135deg, #9CA3AF 0%, #6B7280 100%);
  box-shadow: 0 2px 6px rgba(156, 163, 175, 0.3);
  animation: thinkingPulse 1.5s ease-in-out infinite;
}

.mode-badge.ai-search {
  background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
  box-shadow: 0 2px 6px rgba(59, 130, 246, 0.3);
}

.mode-badge.ai-analysis {
  background: linear-gradient(135deg, #06B6D4 0%, #0891B2 100%);
  box-shadow: 0 2px 6px rgba(6, 182, 212, 0.3);
}

.mode-badge.ai-generation {
  background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);
  box-shadow: 0 2px 6px rgba(245, 158, 11, 0.3);
  animation: generationShine 2s ease-in-out infinite;
}

.mode-badge.ai-final,
.mode-badge.ai-completion {
  background: linear-gradient(135deg, #10B981 0%, #059669 100%);
  box-shadow: 0 2px 6px rgba(16, 185, 129, 0.3);
}

.mode-badge.ai-error {
  background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
  box-shadow: 0 2px 6px rgba(239, 68, 68, 0.3);
}

.mode-badge.ai-file-summary {
  background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
  box-shadow: 0 2px 6px rgba(139, 92, 246, 0.3);
  animation: filePulse 2s ease-in-out infinite;
}

@keyframes thinkingPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

@keyframes generationShine {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

@keyframes filePulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); box-shadow: 0 4px 12px rgba(139, 92, 246, 0.5); }
}

/* Typing Indicator */
.typing-indicator {
  display: flex;
  gap: 8px;
  padding: 16px 20px;
  background: white;
  border-radius: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  border: 1px solid #f3f4f6;
}

.typing-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: linear-gradient(135deg, #0EA5E9 0%, #06B6D4 100%);
  animation: typingBounce 1.4s infinite ease-in-out;
}

.typing-dot:nth-child(1) {
  animation-delay: -0.32s;
}

.typing-dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes typingBounce {
  0%, 80%, 100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1.2);
    opacity: 1;
  }
}

/* Input Area */
.input-area {
  padding: 24px 32px;
  background: white;
  border-top: 1px solid #f3f4f6;
}

.input-container {
  background: #f9fafb;
  padding: 18px 20px;
  border-radius: 24px;
  border: 2px solid #e5e7eb;
  box-shadow: 0 0 0 4px transparent;
  transition: all 0.3s ease;
}

.input-container.focused {
  border-color: #0EA5E9;
  background: white;
  box-shadow: 0 0 0 4px rgba(14, 165, 233, 0.1);
}

.input-wrapper {
  position: relative;
  width: 100%;
}

.floating-label {
  position: absolute;
  left: 0;
  top: 0;
  font-size: 15px;
  color: #9ca3af;
  pointer-events: none;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  transform-origin: left top;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: 6px;
  line-height: 1.6;
}

.label-icon {
  font-size: 16px;
  margin-top: 1px;
}

.floating-label.active {
  opacity: 0;
  transform: translateY(-8px) scale(0.85);
}

.input-box {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  position: relative;
  z-index: 2;
}

textarea {
  flex: 1;
  border: none;
  outline: none;
  resize: none;
  font-size: 15px;
  font-family: inherit;
  line-height: 1.6;
  max-height: 150px;
  min-height: 24px;
  background: transparent;
  color: #1f2937;
  padding: 0;
  margin: 0;
  vertical-align: top;
}

textarea:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.action-buttons {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.send-button {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: #e5e7eb;
  color: #9ca3af;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  flex-shrink: 0;
  position: relative;
}

.send-button.active {
  background: linear-gradient(135deg, #0EA5E9 0%, #06B6D4 100%);
  color: white;
  box-shadow: 0 4px 12px rgba(14, 165, 233, 0.4);
}

.send-button.active:hover:not(:disabled) {
  transform: scale(1.05) rotate(15deg);
  box-shadow: 0 6px 16px rgba(14, 165, 233, 0.5);
}

.send-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.send-icon {
  transition: transform 0.3s ease;
}

.loading-spinner {
  width: 24px;
  height: 24px;
  position: relative;
}

.spinner-ring {
  width: 100%;
  height: 100%;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.input-hint {
  font-size: 12px;
  color: #9ca3af;
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 8px;
}

.manus-tag {
  display: flex;
  align-items: center;
  gap: 8px;
  background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
  border: 2px solid #d1d5db;
  padding: 6px 14px;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 12px;
  font-weight: 600;
  color: #6b7280;
  outline: none;
  position: relative;
}

.manus-tag:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  border-color: #9ca3af;
}

.manus-tag.active {
  background: linear-gradient(135deg, #0EA5E9 0%, #06B6D4 100%);
  border-color: #0EA5E9;
  color: white;
  box-shadow: 0 4px 16px rgba(14, 165, 233, 0.4);
}

.manus-tag.active:hover {
  box-shadow: 0 6px 20px rgba(14, 165, 233, 0.5);
}

.tag-icon {
  font-size: 16px;
  line-height: 1;
}

.tag-text {
  font-weight: 600;
  letter-spacing: 0.3px;
}

/* Manus Mode Styles */
.message-text.manus-mode {
  background: linear-gradient(135deg, #fefcff 0%, #faf5ff 100%);
  border: 2px solid #e9d5ff;
  padding: 24px;
  line-height: 1.8;
  max-width: 100%;
}

.manus-h2 {
  font-size: 22px;
  font-weight: 700;
  color: #7C3AED;
  margin: 20px 0 12px 0;
  padding-bottom: 8px;
  border-bottom: 2px solid #e9d5ff;
}

.manus-h3 {
  font-size: 18px;
  font-weight: 700;
  color: #8B5CF6;
  margin: 16px 0 10px 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.manus-h3::before {
  content: '📌';
  font-size: 16px;
}

.manus-h4 {
  font-size: 16px;
  font-weight: 600;
  color: #9333EA;
  margin: 12px 0 8px 0;
}

.manus-list-item {
  padding: 8px 0 8px 28px;
  position: relative;
  color: #374151;
  line-height: 1.7;
}

.manus-list-item::before {
  content: counter(list-counter) '.';
  counter-increment: list-counter;
  position: absolute;
  left: 0;
  color: #8B5CF6;
  font-weight: 700;
}

.manus-bullet-item {
  padding: 6px 0 6px 24px;
  position: relative;
  color: #374151;
  line-height: 1.7;
}

.manus-bullet-item::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 14px;
  width: 6px;
  height: 6px;
  background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
  border-radius: 50%;
}

.manus-bold {
  font-weight: 700;
  color: #7C3AED;
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(124, 58, 237, 0.1) 100%);
  padding: 2px 6px;
  border-radius: 4px;
}

.manus-italic {
  font-style: italic;
  color: #8B5CF6;
}

.manus-code {
  background: linear-gradient(135deg, #f3e8ff 0%, #ede9fe 100%);
  color: #7C3AED;
  padding: 3px 8px;
  border-radius: 6px;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 13px;
  font-weight: 600;
  border: 1px solid #e9d5ff;
}

.manus-divider {
  border: none;
  height: 2px;
  background: linear-gradient(90deg, transparent 0%, #e9d5ff 50%, transparent 100%);
  margin: 20px 0;
}

.manus-link {
  color: #8B5CF6;
  text-decoration: none;
  border-bottom: 2px solid #e9d5ff;
  transition: all 0.3s ease;
  font-weight: 600;
}

.manus-link:hover {
  color: #7C3AED;
  border-bottom-color: #8B5CF6;
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(124, 58, 237, 0.1) 100%);
}

.manus-emoji-line {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 8px 0;
  margin: 4px 0;
}

.manus-emoji {
  font-size: 24px;
  flex-shrink: 0;
  filter: drop-shadow(0 2px 4px rgba(139, 92, 246, 0.2));
}

.manus-paragraph-break {
  height: 16px;
}

/* Counter for ordered lists */
.manus-mode {
  counter-reset: list-counter;
}

/* Step Block Styles (参考 SuperAgent.vue) */
.manus-step-block {
  background: linear-gradient(135deg, #f8f9ff 0%, #f3f4ff 100%);
  border-left: 4px solid #8B5CF6;
  border-radius: 12px;
  padding: 16px;
  margin: 12px 0;
  box-shadow: 0 2px 8px rgba(139, 92, 246, 0.1);
  transition: all 0.3s ease;
}

.manus-step-block:hover {
  box-shadow: 0 4px 16px rgba(139, 92, 246, 0.2);
  transform: translateX(4px);
}

.manus-step-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 2px solid rgba(139, 92, 246, 0.2);
}

.step-number {
  background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
  color: white;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 12px;
  letter-spacing: 0.5px;
  box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
}

.step-tool {
  background: rgba(245, 158, 11, 0.15);
  color: #D97706;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 10px;
  border: 1px solid rgba(245, 158, 11, 0.3);
}

.manus-step-content {
  color: #374151;
  line-height: 1.7;
  font-size: 14px;
}

.manus-step-title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0 10px 0;
  padding: 12px 16px;
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.08) 0%, rgba(124, 58, 237, 0.08) 100%);
  border-radius: 10px;
  border-left: 4px solid #8B5CF6;
}

.step-badge {
  background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
  color: white;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 10px;
  letter-spacing: 0.5px;
  flex-shrink: 0;
}

.step-desc {
  color: #374151;
  font-weight: 600;
  font-size: 14px;
  flex: 1;
}

/* Tool Badge */
.tool-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.15) 0%, rgba(217, 119, 6, 0.15) 100%);
  color: #D97706;
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 8px;
  border: 1px solid rgba(245, 158, 11, 0.3);
  margin: 0 4px;
  transition: all 0.3s ease;
}

.tool-badge:hover {
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.25) 0%, rgba(217, 119, 6, 0.25) 100%);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
}

/* File Path */
.file-path {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(124, 58, 237, 0.1) 100%);
  color: #7C3AED;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 8px;
  border: 1px solid rgba(139, 92, 246, 0.3);
  margin: 4px 0;
  font-family: 'Monaco', 'Consolas', monospace;
  word-break: break-all;
  transition: all 0.3s ease;
}

.file-path:hover {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.2) 0%, rgba(124, 58, 237, 0.2) 100%);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
}

/* Web Search Result URL List */
.manus-mode a {
  color: #3B82F6;
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid rgba(59, 130, 246, 0.3);
  transition: all 0.3s ease;
}

.manus-mode a:hover {
  color: #2563EB;
  border-bottom-color: #3B82F6;
  background: rgba(59, 130, 246, 0.1);
  padding: 2px 4px;
  border-radius: 4px;
}

/* Avatar Ring Animations for different message types */
.avatar-ring.ai-search,
.avatar-ring.ai-analysis,
.avatar-ring.ai-generation,
.avatar-ring.ai-step {
  animation: avatarPulse 2s ease-out infinite;
}

.avatar-ring.ai-completion {
  border-color: #10B981;
  animation: successPulse 1.5s ease-out infinite;
}

.avatar-ring.ai-error {
  border-color: #EF4444;
  animation: errorShake 0.5s ease-in-out;
}

@keyframes successPulse {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  50% {
    opacity: 0.4;
  }
  100% {
    transform: scale(1.4);
    opacity: 0;
  }
}

@keyframes errorShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* Message wrapper animations for different types */
.message-wrapper.ai-completion {
  animation: slideIn 0.6s ease-out, successGlow 2s ease-in-out infinite 0.6s;
}

@keyframes successGlow {
  0%, 100% {
    box-shadow: 0 0 0 rgba(16, 185, 129, 0);
  }
  50% {
    box-shadow: 0 0 20px rgba(16, 185, 129, 0.2);
  }
}

/* Web Search Card Styles */
.web-search-card {
  margin-top: 12px;
  background: linear-gradient(135deg, #fefeff 0%, #f0f9ff 100%);
  border: 2px solid #bfdbfe;
  border-radius: 16px;
  overflow: hidden;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
}

.web-search-card:hover {
  border-color: #93c5fd;
  box-shadow: 0 4px 16px rgba(59, 130, 246, 0.2);
}

.web-search-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
  cursor: pointer;
  user-select: none;
  transition: all 0.3s ease;
}

.web-search-header:hover {
  background: rgba(59, 130, 246, 0.05);
}

.web-search-icon {
  font-size: 32px;
  flex-shrink: 0;
  filter: drop-shadow(0 2px 6px rgba(59, 130, 246, 0.3));
}

.web-search-info {
  flex: 1;
  min-width: 0;
}

.web-search-title {
  font-size: 15px;
  font-weight: 700;
  color: #2563EB;
  margin-bottom: 4px;
  line-height: 1.4;
}

.web-search-meta {
  font-size: 12px;
  color: #9ca3af;
  font-weight: 500;
}

.expand-icon {
  font-size: 14px;
  color: #9ca3af;
  transition: all 0.3s ease;
  flex-shrink: 0;
}

.expand-icon.expanded {
  transform: rotate(180deg);
  color: #3B82F6;
}

.web-search-content {
  border-top: 1px solid #e5e7eb;
  background: rgba(255, 255, 255, 0.5);
  max-height: 300px;
  overflow-y: auto;
}

.url-list {
  padding: 12px 16px;
}

.url-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 12px;
  margin: 6px 0;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  transition: all 0.3s ease;
}

.url-item:hover {
  border-color: #3B82F6;
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);
  transform: translateX(4px);
}

.url-number {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
  color: white;
  font-size: 11px;
  font-weight: 700;
  border-radius: 50%;
  flex-shrink: 0;
}

.url-link {
  flex: 1;
  color: #3B82F6;
  text-decoration: none;
  font-size: 13px;
  line-height: 1.5;
  word-break: break-all;
  transition: all 0.3s ease;
}

.url-link:hover {
  color: #2563EB;
  text-decoration: underline;
}

/* Slide fade transition */
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}

.slide-fade-leave-active {
  transition: all 0.2s ease-in;
}

.slide-fade-enter-from {
  transform: translateY(-10px);
  opacity: 0;
}

.slide-fade-leave-to {
  transform: translateY(-10px);
  opacity: 0;
}

/* PDF Card Styles */
.pdf-card {
  margin-top: 12px;
  background: linear-gradient(135deg, #fefefe 0%, #f8f9ff 100%);
  border: 2px solid #e9d5ff;
  border-radius: 16px;
  padding: 16px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(139, 92, 246, 0.1);
}

.pdf-card:hover {
  border-color: #c084fc;
  box-shadow: 0 4px 16px rgba(139, 92, 246, 0.2);
  transform: translateY(-2px);
}

.pdf-card-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}

.pdf-icon {
  font-size: 42px;
  flex-shrink: 0;
  filter: drop-shadow(0 2px 6px rgba(139, 92, 246, 0.3));
  animation: pdfIconFloat 3s ease-in-out infinite;
}

@keyframes pdfIconFloat {
  0%, 100% { transform: translateY(0px) rotate(0deg); }
  50% { transform: translateY(-4px) rotate(3deg); }
}

.pdf-info {
  flex: 1;
  min-width: 0;
}

.pdf-title {
  font-size: 15px;
  font-weight: 700;
  color: #7C3AED;
  margin-bottom: 4px;
  word-break: break-all;
  line-height: 1.4;
}

.pdf-meta {
  font-size: 12px;
  color: #9ca3af;
  font-weight: 500;
}

.pdf-card-actions {
  display: flex;
  gap: 10px;
}

.pdf-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  border: none;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  outline: none;
}

.pdf-btn-preview {
  background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
  color: white;
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
}

.pdf-btn-preview:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.pdf-btn-preview:active {
  transform: translateY(0);
}

.pdf-btn-download {
  background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
  color: white;
  box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
}

.pdf-btn-download:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(139, 92, 246, 0.4);
}

.pdf-btn-download:active {
  transform: translateY(0);
}

.btn-icon {
  font-size: 18px;
  line-height: 1;
}

/* Responsive */
@media (max-width: 768px) {
  .chat-room {
    height: 100vh;
    max-height: none;
    border-radius: 0;
  }

  .chat-header {
    padding: 20px 24px;
  }

  .logo-icon {
    font-size: 42px;
  }

  .title-section h1 {
    font-size: 24px;
  }

  .subtitle {
    font-size: 13px;
  }

  .messages-container {
    padding: 20px;
  }

  .message-bubble {
    max-width: 85%;
  }

  .feature-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .suggestion-grid {
    grid-template-columns: 1fr;
  }

  .input-area {
    padding: 16px 20px;
  }
}
</style>
